/*
  socket-kod för chatt mellan 2 personer
  alex, 3 juli 2013
*/

// io-objektet - info om alla sockets, kanaler etc
var io;

// save_log(log, CHAT_ID, users) - sparar en log av konversationen med id CHAT_ID 
// i historiken på varje användare som ingår.
var utils = require('./utils')
, save_log = utils.save_log
, makeid = utils.makeid
, welcome_messages = utils.welcome_messages;


var users = require('./usersAndLogs').users;
// users[USER_ID].history är ett objekt som kommer innehålla chatt-historiken av en användare.
// chat[CHAT_ID] är en lista med triplar (USER_ID, DATE, MESSAGE) som innehåller chatten med ID 'CHAT_ID'.
var chat = {};


// TODO (VALDIGT LÅG PRIO): fixa sa att alla konversationer sedan serverstart inte sparas pa RAM
// Varje chatt har ett unikt (ok, kanske inte, det slumpas, TODO: forsok gora det unikt pa riktigt) chatt-id.


/*
  socket.io - kod. 
  En socket aer typ en oppen kanal till en klient pa andra sidan roren
  som internet rinner genom, klienten kan nar som helst bestamma sig for
  att skicka en forfrogan hit, och koden nedanfor definierar vad som
  ska goras vid en sadan forfragan.
  
  Nar en socket ansluter skapas en 'connection'-forfrogan
  och funktionen hogst upp talar om vad som ska handa da.
  
  En forfragan har ett namn som far vara vad som helst utom
  nagra reserverade namn, se https://github.com/LearnBoost/socket.io-spec#5-event
  (typ 'connection', 'disconnect' osv.)
  Vi anvander de egna namnen
  
  'nick', 'get log' och 'send message'.
  
  TODO: lagg till ett event for att ga ut ur rummet,
  TODO: hantera 'end' genom att avsluta chatten for den andra deltagaren 
  TODO: skriv om koden sa att den blir mer lasbar - ta bort onodiga kommentarer etc.
  TODO: ta reda pa var alla 'socket.broadcast.to(CHAT_ID)' och 'io.sockets.in(CHAT_ID).emit' tar vagen.
  
*/

// TODO: skicka med data från socketIO-lagret
var teteAtete = function (ioFromAbove, socket) {
    io = ioFromAbove;
    if (socket.handshake.headers.cookie === undefined)
        socket.USER_ID = "anon"
    else
        socket.USER_ID = socket.handshake.headers.cookie;

    var USER_ID = socket.USER_ID;

    if (users[USER_ID] === undefined)
        users.add_user(USER_ID);
        
    // socket.join(room) - stoppar in en socket i ett rum
    socket.join('waiting');
    socket.emit("recieve log", ["Waiting for other people..."]);
    console.log('Server - Joined waiting list');

    // Kanse vänta till det finns fler an 2, sa. man kan matcha???
    if (io.sockets.clients('waiting').length >= 2) 
        pair_waiting();
    
    // varje gang det kommer ett 'get log' - request, skicka ivag sa mycket log tillbaka
    socket.on("get log", function(log_size) {
        send_log(log_size, socket);
    });

    
    /* Varje gang det skickas ett meddelande fran klienten 
       (det sker nar man trycker 'submit' efter 'type here' -faltet),
       kommet det ett 'send message' - event. 
       Pa serversidan (har alltsa) sparas meddelandet i chat (TODO: spara nan annanstans),
       och din chatt-kompis far en uppdatering (TODO: fixa broadcast to room)
    */
    socket.on('send message', function(message) {
        console.log("Server: got a message ", message);
        var CHAT_ID = socket.CHAT_ID;
        var USER_ID = socket.USER_ID;
        var log = [];

        // Forsok logga:
        if (CHAT_ID) {
            console.log("send message: chat[CHAT_ID] = ", chat[CHAT_ID]);
            chat[CHAT_ID].push([USER_ID, new Date(), message]);

            log = chat[CHAT_ID].slice(chat[CHAT_ID].length-
                                          Math.min(chat[CHAT_ID].length, 20), 
                                          chat[CHAT_ID].length);
        }

        // skicka till dig sjalv:
        socket.emit('recieve log' , log);
        
        // forsok skicka till andra snubben
        if (socket.otherGuy) {
            socket.otherGuy.emit('recieve log', log);
        }
        else 
            console.log('No broadcasting!');
    });
    
    // När nån lämnar chatten men fortfarande är ansluten till servern
    socket.on('leave chat', function(data) {
        console.log(users);
        console.log(USER_ID);
        socket.leave(socket.room);
        socket.join('waiting');
        if (socket.otherGuy !== undefined) {
            socket.otherGuy.leave(socket.room);
            socket.otherGuy.join('waiting');
            //socket.emit('recieve log', ['Waiting for other people...']);
            socket.otherGuy.emit('recieve log', ['Your partner left, waiting for other people...']);
        }

        // logga konversationen:
        save_log(chat[socket.CHAT_ID].slice(1, chat[socket.CHAT_ID].length-1), socket.CHAT_ID, users);
        socket.emit('recieve log', ['Waiting for other people...']);
        
    });

    // När nån disconnectar tar vi bort den andra ur rummet,
    // sätter i 'waiting' och visar vad som har hänt

    socket.on('disconnect', function(data) {
        if (socket.otherGuy !== undefined) {
            socket.otherGuy.leave(socket.room);
            socket.otherGuy.join('waiting');
            socket.otherGuy.emit('recieve log', ['your partner disconnected, waiting for another...']);
        }

        // logga konversationen:
        save_log(chat[socket.CHAT_ID].slice(1, chat[socket.CHAT_ID].length-1), socket.CHAT_ID, users);
    });

    
    socket.on('get user info', function(data) {
        return users[socket.USER_ID];
    });
};

/*
  Tar 2 socket ur 'waiting', ser till att de lamnar 
  'waiting', de joinar ett nytt rum med unikt id, 
  och satter .otherGuy till respektive.
  Initar array med valkomstmeddelande i chat[DET_UNIKA_ID:T]
*/
var pair_waiting = function() {
    console.log("trying to pair!");
    var socket0 = io.sockets.clients('waiting')[0];
    var socket1 = io.sockets.clients('waiting')[1];
    socket0.leave('waiting');
    socket1.leave('waiting');
    
    var CHAT_ID = makeid(10);
    socket0.CHAT_ID = CHAT_ID
    socket1.CHAT_ID = CHAT_ID;
    socket0.otherGuy = socket1;
    socket1.otherGuy = socket0;

    chat[CHAT_ID] = [[welcome_messages[Math.floor(Math.random()*welcome_messages.length)]]];
    send_log(20, socket0);
    send_log(20, socket1);
    console.log("Pairing sucessfull!");
};

// Skickar log till socket och socket.otherGuy
var send_log = function(num, socket) {
    console.log('twoPersonChat.send_log called');
    var CHAT_ID = socket.CHAT_ID;
    
    if (CHAT_ID) {
        var log = chat[CHAT_ID].slice(chat[CHAT_ID].length-
                                        Math.min(chat[CHAT_ID].length, num), 
                                        chat[CHAT_ID].length);
        if (socket.otherGuy !== undefined)
            socket.otherGuy.emit('recieve log', log);
        socket.emit('recieve log', log);
    }
    else 
        console.log('No broadcasting!');
};

exports.teteAtete = teteAtete;
